<?php declare(strict_types=1);
/**
 * @author      xianganyall <xianganyall@gmail.com>
 * @copyright   2023-2025 owner
 **/

namespace Srv\Libs\Plugins\Qc;

use Exception;
use Srv\Libs\Common\CommJson;
use Srv\Libs\Common\CommValid;
use Srv\Libs\Frame\Logs;
use TencentCloud\Common\Credential;
use TencentCloud\Ses\V20201002\Models\SendEmailRequest;
use TencentCloud\Ses\V20201002\Models\Simple;
use TencentCloud\Ses\V20201002\Models\Template;
use TencentCloud\Ses\V20201002\SesClient;

class QcEmail
{
    private string $apiKey                  = '';               // apiKey
    private string $secretKey               = '';               // secretKey
    private string $logPath                 = '';               // logPath
    private string $region                  = 'ap-hongkong';    // region

    /**
     * @param string $apiKey
     * @param string $secretKey
     * @param string $logPath
     * __construct
     */
    public function __construct(string $apiKey, string $secretKey, string $logPath)
    {
        $this->apiKey       = $apiKey;
        $this->secretKey    = $secretKey;
        $this->logPath      = $logPath;
    }

    /**
     * @param array $toList
     * @param string $from
     * @param string $fromName
     * @param string $subject
     * @param string $htmlBody
     * @return bool
     * 发送Html邮件
     */
    public function sendMailHtml(array $toList, string $from, string $fromName, string $subject, string $htmlBody):bool
    {
        if(count($toList) < 1 || !CommValid::isEmail($from) || strlen($subject) < 1 || strlen($htmlBody) < 1) return false;
        $toEmailList            = [];
        foreach($toList as $to){
            if(!is_string($to) || !CommValid::isEmail($to)) continue;
            $toEmailList[]      = $to;
        }
        if(count($toEmailList) < 1) return false;
        $emailData              = ['Destinations' => $toEmailList];
        try{
            $Simple             = new Simple();
            $Simple->setHtml(base64_encode($htmlBody));
            $SendEmailRequest   = new SendEmailRequest();
            $SendEmailRequest->setDestination($toEmailList);
            $SendEmailRequest->setFromEmailAddress($fromName.' <'.$from.'>');
            $SendEmailRequest->setReplyToAddresses($from);
            $SendEmailRequest->setSubject($subject);
            $SendEmailRequest->setSimple($Simple);
            $Credential         = new Credential($this->apiKey, $this->secretKey);
            $SesClient          = new SesClient($Credential, $this->region);
            $SendEmailResponse  = $SesClient->SendEmail($SendEmailRequest); // docs: https://cloud.tencent.com/document/api/1288/51034
            $resJsonStr         = $SendEmailResponse->toJsonString();
            $resData            = CommJson::decode($resJsonStr);
            if(isset($resData['MessageId']) && strlen($resData['MessageId']) > 0){
                $this->writeLog(CommJson::encodeArray(['res' => 'OK', 'POST' => $emailData, 'RES' => $resJsonStr]), __LINE__, __FILE__);
                return true;
            }
            $this->writeLog(CommJson::encodeArray(['res' => 'FAIL', 'POST' => $emailData, 'RES' => $resJsonStr]), __LINE__, __FILE__);
            return false;
        }catch (Exception $Exception){
            $this->writeLog(CommJson::encodeArray(['res' => 'FAIL', 'POST' => ['Destinations' => $toEmailList], 'RES' => $Exception->getMessage()]), __LINE__, __FILE__);
            return false;
        }
    }

    /**
     * @param array $toList
     * @param string $from
     * @param string $fromName
     * @param string $subject
     * @param string $content
     * @return bool
     * 发送文本邮件
     */
    public function sendMailText(array $toList, string $from, string $fromName, string $subject, string $content):bool
    {
        if(count($toList) < 1 || !CommValid::isEmail($from) || strlen($subject) < 1 || strlen($content) < 1) return false;
        $toEmailList            = [];
        foreach($toList as $to){
            if(!is_string($to) || !CommValid::isEmail($to)) continue;
            $toEmailList[]      = $to;
        }
        if(count($toEmailList) < 1) return false;
        $emailData              = ['Destinations' => $toEmailList];
        try{
            $Simple             = new Simple();
            $Simple->setText(base64_encode($content));
            $SendEmailRequest   = new SendEmailRequest();
            $SendEmailRequest->setDestination($toEmailList);
            $SendEmailRequest->setFromEmailAddress($fromName.' <'.$from.'>');
            $SendEmailRequest->setReplyToAddresses($from);
            $SendEmailRequest->setSubject($subject);
            $SendEmailRequest->setSimple($Simple);
            $Credential         = new Credential($this->apiKey, $this->secretKey);
            $SesClient          = new SesClient($Credential, $this->region);
            $SendEmailResponse  = $SesClient->SendEmail($SendEmailRequest);
            $resJsonStr         = $SendEmailResponse->toJsonString();
            $resData            = CommJson::decode($resJsonStr);
            if(isset($resData['MessageId']) && strlen($resData['MessageId']) > 0){
                $this->writeLog(CommJson::encodeArray(['res' => 'OK', 'POST' => $emailData, 'RES' => $resJsonStr]), __LINE__, __FILE__);
                return true;
            }
            $this->writeLog(CommJson::encodeArray(['res' => 'FAIL', 'POST' => $emailData, 'RES' => $resJsonStr]), __LINE__, __FILE__);
            return false;
        }catch (Exception $Exception){
            $this->writeLog(CommJson::encodeArray(['res' => 'FAIL', 'POST' => ['Destinations' => $toEmailList], 'RES' => $Exception->getMessage()]), __LINE__, __FILE__);
            return false;
        }
    }

    /**
     * @param array $toList
     * @param string $from
     * @param string $fromName
     * @param string $subject
     * @param string $templateId
     * @param array $templateData
     * @return bool
     * 发送模板邮件
     */
    public function sendMailTemplate(array $toList, string $from, string $fromName, string $subject, string $templateId, array $templateData):bool
    {
        if(count($toList) < 1 || !CommValid::isEmail($from) || strlen($subject) < 1 || strlen($templateId) < 1) return false;
        $toEmailList            = [];
        foreach($toList as $to){
            if(!is_string($to) || !CommValid::isEmail($to)) continue;
            $toEmailList[]      = $to;
        }
        if(count($toEmailList) < 1) return false;
        $emailData              = ['Destinations' => $toEmailList];
        try{
            $Template           = new Template();
            $Template->setTemplateID(intval($templateId));
            if(count($templateData) > 0) $Template->setTemplateData(CommJson::encodeArray($templateData));
            $SendEmailRequest   = new SendEmailRequest();
            $SendEmailRequest->setDestination($toEmailList);
            $SendEmailRequest->setFromEmailAddress($fromName.' <'.$from.'>');
            $SendEmailRequest->setReplyToAddresses($from);
            $SendEmailRequest->setSubject($subject);
            $SendEmailRequest->setTemplate($Template);
            $Credential         = new Credential($this->apiKey, $this->secretKey);
            $SesClient          = new SesClient($Credential, $this->region);
            $SendEmailResponse  = $SesClient->SendEmail($SendEmailRequest); // docs: https://cloud.tencent.com/document/api/1288/51034
            $resJsonStr         = $SendEmailResponse->toJsonString();
            $resData            = CommJson::decode($resJsonStr);
            if(isset($resData['MessageId']) && strlen($resData['MessageId']) > 0){
                $this->writeLog(CommJson::encodeArray(['res' => 'OK', 'POST' => $emailData, 'RES' => $resJsonStr]), __LINE__, __FILE__);
                return true;
            }
            $this->writeLog(CommJson::encodeArray(['res' => 'FAIL', 'POST' => $emailData, 'RES' => $resJsonStr]), __LINE__, __FILE__);
            return false;
        }catch (Exception $Exception){
            $this->writeLog(CommJson::encodeArray(['res' => 'FAIL', 'POST' => ['Destinations' => $toEmailList], 'RES' => $Exception->getMessage()]), __LINE__, __FILE__);
            return false;
        }
    }

    /**
     * @param string $logString
     * @param int $fileLine
     * @param string $filePath
     * @return void
     * writeLog
     */
    private function writeLog(string $logString, int $fileLine, string $filePath):void
    {
        if(strlen($this->logPath) > 0) Logs::info($logString, $fileLine, $filePath, $this->logPath);
    }
}
